package com.googlecode.serialization;


public class MarkSerializingTranscoder extends AbsSerializingTranscoder implements Transcoder<Object> {

	private final SerializingTranscoder serializingTranscoder;

	public MarkSerializingTranscoder(int maxSize) {
		serializingTranscoder = new SerializingTranscoder(maxSize);
		serializingTranscoder.setPackZeros(false);
		serializingTranscoder.setPrimitiveAsString(false);
	}

	public MarkSerializingTranscoder() {
		serializingTranscoder = new SerializingTranscoder();
		serializingTranscoder.setPackZeros(false);
		serializingTranscoder.setPrimitiveAsString(false);
	}

	public void setCompressionMode(CompressionMode compressMode) {
		this.serializingTranscoder.setCompressionMode(compressMode);
	}

	@Override
	public Object decode(DataInfo d) {
		byte[] compositeData = d.getData();
		if (compositeData.length <= 4)
			throw new IllegalArgumentException("There are no four bytes before value for MarkSerializingTranscoder");
		byte[] flagBytes = new byte[4];
		byte[] realData = new byte[compositeData.length - 4];
		System.arraycopy(compositeData, 0, flagBytes, 0, 4);
		System.arraycopy(compositeData, 4, realData, 0,
				compositeData.length - 4);
		int flag = serializingTranscoder.getTranscoderHelper().decodeInt(	flagBytes);
		d.setFlag(flag);
		if ((flag & SerializingTranscoder.COMPRESSED) != 0) {
			realData = serializingTranscoder.uncompress(realData);
		}
		flag = flag & SerializingTranscoder.SPECIAL_MASK;
		return serializingTranscoder.decode0(d, realData, flag);
	}

	@Override
	public DataInfo encode(Object o) {
		DataInfo dif = serializingTranscoder.encode(o);
		byte[] rd = dif.getData();
		int flag = dif.getFlag();
		byte[] flagBytes = serializingTranscoder.getTranscoderHelper().encodeInt(flag);

		byte[] compisiteData = new byte[4 + rd.length];
		System.arraycopy(flagBytes, 0, compisiteData, 0, 4);
		System.arraycopy(rd, 0, compisiteData, 4, rd.length);

		dif.setData(compisiteData);
		return dif;
	}

	public final int getMaxSize() {
		return serializingTranscoder.getMaxSize();
	}

	public boolean isPackZeros() {
		return serializingTranscoder.isPackZeros();
	}

	public boolean isPrimitiveAsString() {
		return serializingTranscoder.isPrimitiveAsString();
	}

	public void setCharset(String to) {
		serializingTranscoder.setCharset(to);
	}

	public void setCompressionThreshold(int to) {
		serializingTranscoder.setCompressionThreshold(to);
	}

	@Override
	public void setPackZeros(boolean packZeros) {
		throw new UnsupportedOperationException("MarkSerializingTranscoder doesn't support pack zeros");
	}

	@Override
	public void setPrimitiveAsString(boolean primitiveAsString) {
		throw new UnsupportedOperationException("MarkSerializingTranscoder doesn't support save primitive type as String");
	}

}
